import Line from './Line.js'
import Path from './Path.js'

/**
 * 路线管理
 * 存放所有路线及路线上的站点
 * {
 *    XX线: {
 *      name: 'XX线',
 *      stationNameList: [xx站, yy站],
 *      isRing: 1
 *    }
 *    ZZ线: {...}
 * }
 * 
 */
class LineManager {
  constructor() {
    this.lineMap = new Map()
  }
  
  /**
   * @param {String} lineName
   * @param {String} stationName
   * @param {Integer} isRing  0=否 1=是
   */
  addStation(lineName, stationName, isRing) {
    if (this.lineMap.has(lineName)) {
      this.lineMap.get(lineName).addStationName(stationName)
    } else {
      const line = new Line(lineName, isRing)
      line.addStationName(stationName)
      this.lineMap.set(lineName, line)
    }
  }
  
  /**
   * 计算能直达（不换乘）两站之间距离最短的坐方案
   * @param {String} fromStationName
   * @param {String} toStationName
   * @param {Object} lineNameList
   */
  getBestPath(fromStationName, toStationName, lineNameList) {
    const path = new Path()
    path.fromStationName = fromStationName
    path.toStationName = toStationName
    
    if (lineNameList.length == 0) {
      return path
    }
    
    lineNameList.forEach(lineName => {
      const line = this.lineMap.get(lineName)
      let fromIndex = 0
      let toIndex = 0
      
      line.stationNameList.forEach((stationName, index) => {
        if (stationName == fromStationName) {
          fromIndex = index
        } else if (stationName == toStationName) {
          toIndex = index
        }
      })
      
      // 起始站索引不可能大于或小于终点索引，取绝对值
      let distance = Math.abs(fromIndex - toIndex)
      
      if (line.isRing == 1) {
        const leftDistance = line.stationNameList.length - distance
        distance = (leftDistance < distance) ? leftDistance : distance
      }
      
      if (distance < path.distance) {
        path.distance = distance
        path.lineName = line.name
      }
      
    })
    return path
  }
  
  /**
   * 按照普通线路方式 给定索引返回两站之间所经过的站点
   * @param {Integer} fromIndex
   * @param {Integer} toIndex
   * @param {Array}   stationNameList
   */
  getStationListByIndex(fromIndex, toIndex, stationNameList) {
    return (toIndex >= fromIndex) ? stationNameList.slice(fromIndex, toIndex + 1)
                                  : stationNameList.slice(toIndex, fromIndex + 1).reverse()
  }
  
  /**
   * 按环线方式 给定索引返回两站之间所经过的站名集合
   * @param {Integer} fromIndex
   * @param {Integer} toIndex
   * @param {Array} stationNameList
   */
  getRingStationByIndex(fromIndex, toIndex, stationNameList) {
    let list = null
    if (fromIndex < toIndex) {
      list = stationNameList.slice(0, fromIndex + 1).reverse().concat(stationNameList.slice(toIndex).reverse())
    } else {
      list = stationNameList.slice(fromIndex).concat(stationNameList.slice(0, toIndex + 1))
    }
    
    return list
  }
  
  /**
   * 给定线路上从起始站到终点站所经过站点名集合
   * @param {String} lineName
   * @param {String} fromStationName
   * @param {String} toStationName
   */
  getPathStationNameList(lineName, fromStationName, toStationName) {
    const line = this.lineMap.get(lineName)
    
    if (!line) {
      return []
    }
    
    const stationNameList = line.stationNameList
    let pathStationNameList = null
    
    const fromIndex = stationNameList.indexOf(fromStationName)
    const toIndex = stationNameList.indexOf(toStationName)
    
    const distance = Math.abs(fromIndex - toIndex)
    const leftDistance = stationNameList.length - distance
    
    // 是环线且往反方向距离更近时用环线方式
    // 正方向距离更近时用普通线路方式
    if (line.isRing == 1 && leftDistance < distance) {
      pathStationNameList = this.getRingStationByIndex(fromIndex, toIndex, stationNameList)
    } else {
      pathStationNameList = this.getStationListByIndex(fromIndex, toIndex, stationNameList)
    }
    return pathStationNameList
  }
}


export default LineManager